package com.thoughtservice.jspdoc;

/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is "JSP Documentation Generator Project".
 *
 */

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import gnu.regexp.*;

/**
 * Wrapper-class to translate jakarta-regexp method calls to
 * GNU-regexp methods.
 * Becaus GNU-regexp does not provide a split method this is
 * additionally implemented.
 *
 * @author Jochen Luell (jochen@luell.com)
 */
public class RE
{
	private final static Logger LOG = LoggerFactory.getLogger(RE.class);
			
     private REMatch lastMatch;
     private gnu.regexp.RE re;
     
     public static void main(String[] args) {
		try {
			//RE regExp = new RE("<%[:space:]*@[:space:]*page[:space:]*.*?import=\"([:print:]*?)\"[:print:]*%>");
			//System.out.println(regExp.match("<%@page import=\"java.util.Map\"%>"));
			String ob = "<%-- <%@include file=\"body/user-form-body.jsp\" %>   --%>";
			//RE regExp = new RE("<%--*[:space:]*<%@[:space:]*include[:space:]*file=\"\\S*\"[:space:]*%>*[:space:]*--%>");
			RE regExp = new RE("<%@[:space:]*include[:space:]*file=\"\\S*\"[:space:]*%>");
			System.out.println(regExp.match(ob));
			System.out.println(ob);
			if(ob.startsWith("<%--"))
				ob = ob.replaceAll("<%--", "");
			//ob = regExp.subst(ob, "");
			System.out.println(ob);
		} catch (RESyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

     /**
      * Class constructor
      *
      * @param pattern java.lang.String The regexp pattern
      */
     public RE(String pattern) throws RESyntaxException{
        try {
            pattern = "(" + pattern + ")";
            gnu.regexp.RE convert;

            convert= new gnu.regexp.RE("(\\[:[a-z]+:\\])");
            pattern = convert.substituteAll(pattern, "[$1]");

            RESyntax syntax = new RESyntax();

            syntax.set(RESyntax.RE_CHAR_CLASSES);
            syntax.set(RESyntax.RE_STINGY_OPS);
            syntax.set(RESyntax.RE_NO_BK_PARENS);
            syntax.set(RESyntax.RE_CHAR_CLASS_ESCAPES);

            re = new gnu.regexp.RE(pattern, gnu.regexp.RE.REG_ICASE|gnu.regexp.RE.REG_DOT_NEWLINE,
                                            syntax); 
        }
        catch(REException e) {
            throw new RESyntaxException(e.getMessage());
        }
     }

     /**
      * Matches the regexp pattern against the given input string.
      * This method translates jakarta-regexp <code>match(String)</code> to
      * GNU-regexp <code>getMatch(String)</code>.
      *
      * @param input java.lang.String Input String
      * @return boolean
      */
     public boolean match(String input) {
        this.lastMatch = re.getMatch(input);
        boolean ret = this.lastMatch != null ? true:false;
        return ret;
     }


     /**
      * Matches the regexp pattern against the given input string startig from
      * given index position.
      * This method translates jakarta-regexp <code>match(String, int)</code> to
      * GNU-regexp <code>getMatch(String, int)</code>.
      *
      * @param input java.lang.String Input String
      * @param index int Index to start comparison
      * @return boolean
      */
     public boolean match(String input, int index) {
    	 LOG.trace("Entering {}", "match");
    	 LOG.debug("input {} index {}", input, index);
        this.lastMatch = re.getMatch(input, index);       
        return this.lastMatch != null ? true:false;
        
     }

     /**
      * Returns all matches in given input string and supplied group.
      * If group is 0 matches apply to complete result string.
      *
      * @param input java.lang.String Input String
      * @param group java.lang.String Group to return value for
      * @return java.lang.String[] Resulting String array
      */
     public String[] getAllMatches(String input, int group) {
       int ic = 0;
       List<String> marray = new ArrayList<String>();

       while(this.match(input, ic)) {
           String matchRes = this.getParen(group);
           ic = this.getParenEnd(group);
           marray.add(matchRes);
       }

       String[] ret = (String[]) marray.toArray(new String[marray.size()]);

       return ret;
     }

     /**
      * Gests result of ParenGroup (grouping operator).
      * This method translates jakarta-regexp <code>getParen(int)</code> to
      * GNU-regexp <code>lastMatch.toString(int)</code>.
      *
      * @param group int Group index
      * @return java.lang.String Result string
      */
     public String getParen(int group) {
      String ret;
      try {
        ret = this.lastMatch.toString(group + 1);
      }
      catch (NullPointerException e) {
        ret = null;
      }

      if(ret != null)      	
        return ret;
      else
    	  return null;
     }
     /**
      * Returns end index of given ParenGroup
      * This method translates jakarta-regexp <code>getParenEnd(int)</code> to
      * GNU-regexp <code>lastMatch.getEndIndex(int)</code>.
      *
      * @param group int Group index
      * @return int End index
      */
     public int getParenEnd(int group) {
          int ret = this.lastMatch.getEndIndex(group + 1);
          return ret;
     }

     /**
      * Performs substitution within input String.
      * This method translates jakarta-regexp <code>subst(String, String)</code> to
      * GNU-regexp <code>substituteAll(String, String)</code>.
      *
      * @param from java.lang.String String to perform substitution on
      * @param from java.lang.String Replacement string
      * @return java.lang.String Result string
      */
     public String subst(String from, String to) throws RESyntaxException {
           String ret = re.substituteAll(from, to);
           return ret;
     }

     /**
      * Splits the given input string.
      * This method splits an input string and returns the result as String
      * Array..
      *
      * @param input java.lang.String String to split
      * @return java.lang.String[] Resulting String Array
      */
     public String[] split(String input) {
       int i,si;
       List<String> result = new ArrayList<String>();

       REMatch[] matches = re.getAllMatches(input);

       for (i = 0, si = 0; i < matches.length; i++) {
	    result.add(input.substring(si, matches[i].getStartIndex()));
	    si = matches[i].getEndIndex();
	}
 
       if (i != input.length()) {
	    result.add(input.substring(si, input.length()));
	}


       String[] ret = (String[]) result.toArray(new String[result.size()]);
        
        return ret;
     }
}
